<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<!--
			
			MVC,MVVM的理解：
				在MVC中，View可以直接访问model，因此，View将包含Model信息，并且不可避免地包含一些业务逻辑。】MVC模型侧重于model的不变性，并且view是单向依赖于model。】不仅如此，由于某些业务逻辑是在View中实现的，因此很难更改View，至少那些业务逻辑无法重用。
				MVVM是“双向绑定数据模型数据”的核心，因此View和Model之间没有连接，通过ViewModel进行交互，】MVC是单向通信。也就是说，View和Model必须得到Controller的支持。】MVC和MVVM之间的区别并不在于VM完全取代C。ViewModel的目的是提取Controller中显示的业务逻辑，而不是替换Controller。其他视图操作服务应在Controller中实现，换句话说，MVVM实现了业务逻辑组件的重用。
				资料拓展：MVVM模式试图获得MVC提供的功能性开发分离的两个优点，同时利用数据绑定的优势和通过绑定数据的框架尽可能接近纯应用程序模型。它使用绑定器、视图模型和任何业务层的数据检查功能来验证传入的数据。			
			对vue的理解：
				使用vue【不必担心】布局更改及类名重复导致js的重写，它本身是【靠数据驱动来双向绑定】的，
				  其次，它【拓展性好，移植性高，代码可重用性强】，
				 单页面应用的体验更加接近安卓的原生应用的体验，【局部更新界面，让用户体验更快速省事】，
				 团队合作的话，【代码的阅读性高，可引入其他组件】，相当于提高了代码的可维护性	
			vue传值方式：
				父子：父组件给子组件绑定一个自定义属性，然后子组件注册一个对应的自定义属性，把这个自定义属性当作数据接收,
					调用子组件方法通过在父组件获取ref并使用emit发射方法出去，在子组件那里一开始用on监听然后接收发射过来的数据即可，或者ref直接获取调用
				子父：子组件this.$emit(‘相同’,数据),父组件this.$on(‘相同’,fn(){})，或者，v-on:接收的函数名='调用的父组件函数名并带参数'
				兄弟：同上的this改为第三方实例，就行，也可以使用vuex进行传值
				视图可直接自定义属性让在视图里面展示的组件可以接收
			vue,$set和$delete：
				this.$set(对象，key，value)，动态为要添加属性的对象追加属性
			vuex:
				main或者组件里面里面引入store.js，然后new vue里面注册store（一般这样子，），然后在引入的那个js里面引入vue跟vuex，并Vue.use(vuex)，然后const store = new Vuex.Store({.....});export default store;
				state:储存数据
				mutations：修改数据，传入state参数获取state对象,
					this.$store.commit（‘方法’,传入的数据（方法里面第二个参数开始））
				actions：可以设置方法，传入context参数来调用mutations里面的方法：context.commit（‘方法 ’），直接一点就传入{commit}这个再commit('方法')，{commit ,state}表示可以调用mutations的方法和使用state的数据，
					this.$store.dispatch('方法',传入的数据（方法里面第二个参数开始）)，
					actions相比于mutations，不受同步的限制，它可以进行异步处理，mutations不可以，必须进行同步处理
				getters：vuex里面的计算属性，定义一个函数，监听并返回一个处理后的数据，
					this.$store.getters.方法，直接拿出来，不用括号，就会返回出来一个值
				进阶用法：
				import { mapMutations } 或者 { mapActions } from 'Vuex'
					methods里面：...mutations(['方法'])，相当于直接调用方法this.方法，actions也是一样，但这种方法适用于无参数传入
			vue路由守卫：
				路由获取meta：$route.meta,
				路由守卫获取meta：to.meta/from.meta
				全局路由守卫：
					main.js里面加入router.beforeEach((to, from, next) => {})
					里面必须带next()实现跳转，不然这个路由守卫无意义，
					通过判断路由的meta是否存在to。meta。XXX并做相应的业务逻辑，不存在就next（{path：‘/XXX’}）存在就正常跳转
					---
					to。fullPath ==‘/XXX’，但是想要重定向，可以再次判断状态跳转到相应的地方
				局部路由守卫(不可设置在子组件里面)：
					 beforeRouteEnter(to,from,next){//获取不了this
			            next((vm)=>{ //参数vm就是当前组件的实例data。
			                vm.test = '我被改变了'
			            })
			        },
			        beforeRouteUpdate(to,from,next){
			            next()//false，不允许跳转，{path：‘/XXX’}，指定路径，不写就正常跳转
			        },
			        beforeRouteLeave(to,from,next){//离开组件的时候触发
			            next()
			        }
			vue的keep-alive标签：
				include:'a,b',要缓存的组件的name属性的值，组件当中要设置name属性并与data同级
				exclude：不需要缓存的组件
				使用keep-alive标签包裹的组件或标签，都会被缓存起来，但是组件的话，组件里面会多出activated 与 deactivated两个钩子函数，要想再次显示时触发函数，就使用activated来进行触发，如果停用组件，就用deactivated；
			vue阻止页面离开：
				beforeRouteLeave(to, from, next) {
					//保存与否的flag来判断next()可跳转跟为保存时弹框确定next()和取消next(false)
				}
			
			//vue3.0
			
			vue3.0的setup组合api
				第一种写法：
				props：{}，
				setup(props){
					  var title = ref('32535')//值
					  var theobj = reactive({name:35435})
					  var arr = reactive([1,2,3,4,5,7,8])
					  watch([1,2],([new,new],[old,old]) => {})
					  const doubleCounter = computed(() => {
							//比如
							return state.count * 2//state.count一经修改，computed里面的这个就会一起响应，返回到doubleCounter那里
							// return  state.msgSet.length
						})
					  return {
						  title,theobj,arr,
						  changetitle:()=>{//可直接调用
							  title.value = '33534'
							  theobj.name = 43543543
							  console.log(title.value,theobj.name)
							  for(var i=0;i<arr.length;i++){
								  arr[i] = arr[i] + 1
								  console.log(arr[i])
							  }
						  }，
						  doubleCounter
					  }
				}
				第二种写法：
				script setup写法
				const props = defineprops({})
				const list = props.list//假设的数据，可以直接使用
				const watch = watch([1,2],([new,new],[old,old]) => {}) // 中括号里面可以是数据，props，可以是响应式对象，响应式对象里面的某个属性
				然后其他写法一样
				const doubleCounter = computed(() => {
					//比如
					return state.count * 2//state.count一经修改，computed里面的这个就会一起响应，返回到doubleCounter那里
					// return  state.msgSet.length
				})

				尽量使用import方式引入组件，vue3无法通过直接import懒加载的方式引入组件
				vue3里面如果有存在按需引入的组件，export default { 改成 export default defineComponent({
					一个vue-draggable拖拽例子：
					import { defineComponent } from 'vue'
					import { VueDraggableNext } from 'vue-draggable-next'
					export default defineComponent({})

				语法糖的钩子需要加上on，引入进来使用然后回调处理逻辑，参数跟旧版一样


			为什么在 Vue3.0 采用了 Proxy，抛弃了 Object.defineProperty？
				Object.defineProperty无法监控到数组下标的变化，导致通过数组下标添加元素，不能实时响应；
				Object.defineProperty只能劫持对象的属性，从而需要对每个对象，每个属性进行遍历，如果，属性值是对象，还需要深度遍历。Proxy可以劫持整个对象，并返回一个新的对象。
				Proxy不仅可以代理对象，还可以代理数组。还可以代理动态增加的属性。
		-->
	</body>
</html>
